import BaseCURDV2Api from '@/framework/infra/base/BaseCURDV2Api'
import DeliveryComplainStatusEnum from '@/feature/cmt/infra/constants/DeliveryComplainStatusEnum'
import moment from 'moment'
import PayOutTypeEnum from '@/feature/cmt/infra/constants/PayOutTypeEnum'

class DeliveryComplainApi extends BaseCURDV2Api {
  constructor() {
    super('cmt/delivery-complain')
  }

  follow(data) {
    return this.post('follow', data)
  }

  submit({ id, remark = '' }) {
    return this.post('submit', { id, remark })
  }

  dataCount() {
    return this.get('data-count').then(data => {
      if (!data) {
        return {}
      }
      return this.parseDataCount(data)
    })
  }

  parseDataCount(data) {
    const map = data.reduce((r, a) => {
      let status = a.status
      if (status === DeliveryComplainStatusEnum.ING.id) {
        status = DeliveryComplainStatusEnum.WAIT_FOLLOW.id
      }
      r[status] = r[status] || 0
      r[status] += a.count
      return r
    }, {})
    return DeliveryComplainStatusEnum.getKeys().reduce((r, a) => {
      r[a] = r[a] || 0
      r[a] += map[DeliveryComplainStatusEnum[a].id] || 0
      return r
    }, {})
  }

  followReject(data) {
    return this.post('follow-reject', data)
  }

  listCanFollow(data) {
    const getParams = {...data}
    Object.keys(getParams).forEach(key => {
      if (Array.isArray(getParams[key])) {
        getParams[key] = getParams[key].join(',')
      }
    })
    return this.get('list-can-follow', getParams)
  }

  listMyFollow(data) {
    const getParams = {...data}
    Object.keys(getParams).forEach(key => {
      if (Array.isArray(getParams[key])) {
        getParams[key] = getParams[key].join(',')
      }
    })
    return this.get('list-my-follow', getParams)
  }

  listCanCheck(data) {
    const getParams = {...data}
    Object.keys(getParams).forEach(key => {
      if (Array.isArray(getParams[key])) {
        getParams[key] = getParams[key].join(',')
      }
    })
    return this.get('list-can-check', getParams)
  }

  queryTotalRevocationRate(data = {}) {
    return this.get('total-revocation-rate', data)
  }

  queryRevocationRateByStore(data = []) {
    const param = {}
    if (data && data.length) {
      param.startDate = data[0]
      param.endDate = data[1]
    }
    return this.get('revocation-rate-by-store', param)
  }

  _arrSum(arr, startIdx, endIdx) {
    return arr.slice(startIdx, endIdx).reduce((r, a) => {
      return r + a
    }, 0)
  }

  queryRevocationRateByStoreAndFollowerId({ dateRange: data, ...param }) {
    if (data && data.length) {
      param.startDate = data[0]
      param.endDate = data[1]
    }
    return this.get('revocation-rate-by-store-follower', param).then(data => {
      let storeId = ''
      let firstIdx = 0
      const results = []
      for (let idx = 0; idx < data.length; idx++) {
        const item = data[idx]
        if (storeId === '') {
          storeId = item.storeId
        } else if (storeId !== item.storeId) {
          data[firstIdx].rowSpan = idx - firstIdx
          storeId = item.storeId
          results.push({
            storeTitle: '汇总',
            storeTitleColSpan: 2,
            rowSpan: 1,
            storeTotalNum: data[firstIdx].storeTotalNum,
            storeBackOutNum: data[firstIdx].storeBackOutNum,
            storeBadNum: data[firstIdx].storeBadNum,
            storePayOutAmount: data[firstIdx].storePayOutAmount,
            backOutNum: data[firstIdx].storeBackOutNum, // this._arrSum(data.map(el => el.backOutNum), firstIdx, idx - 1),
            payOutAmount: data[firstIdx].storePayOutAmount,
            payOutAmountPercent: '100%',
            backOutNumPercent: '100%'
          })
          firstIdx = idx
        }
        item.storeTitleColSpan = 1
        item.payOutAmountPercent += '%'
        item.backOutNumPercent += '%'
        results.push(item)
      }
      if (results && results.length) {
        data[firstIdx].rowSpan = data.length - firstIdx
        const item = data[firstIdx]
        results.push({
          storeTitle: '汇总',
          storeTitleColSpan: 2,
          rowSpan: 1,
          storeTotalNum: item.storeTotalNum,
          storeBackOutNum: item.storeBackOutNum,
          storeBadNum: item.storeBadNum,
          storePayOutAmount: item.storePayOutAmount,
          backOutNum: item.storeBackOutNum, // this._arrSum(data.map(el => el.backOutNum), firstIdx, idx - 1),
          payOutAmount: item.storePayOutAmount,
          payOutAmountPercent: '100%',
          backOutNumPercent: '100%'
        })
      }
      return results
    })
  }

  queryRevocationRateByFollowerId(data = []) {
    const param = {}
    if (data && data.length) {
      param.startDate = data[0]
      param.endDate = data[1]
    }
    return this.get('revocation-rate-by-follower', param)
  }

  queryRevocationRateByUserDaily({
    payOutType = null,
    dateRange
  }) {
    return this.get('revocation-rate-by-user-daily', {
      payOutType,
      startDate: dateRange[0],
      endDate: dateRange[1]
    })
  }

  queryStoreStaticByPayOutType({
    storeId = '',
    dateRange
  }) {
    return this.get('store-by-pay-out-data-count', {
      storeId,
      startDate: dateRange[0],
      endDate: dateRange[1]
    }).then(dataList => {
      const result = dataList.map(data => {
        const payOutTypeMap = data.payOutTypeData.reduce((r, a) => {
          r[a.payOutType] = a
          return r
        }, {})
        data.typeData = {}
        PayOutTypeEnum.getOptions().forEach(op => {
          const map = payOutTypeMap[op.value] || {}
          map.label = op.label
          if (op.value === PayOutTypeEnum.AUTO.id || op.value === PayOutTypeEnum.TS.id) {
            map.originPayOutAmount = 0
            map.leftAmount = 0
          }
          data.typeData[op.value] = map
        })
        console.log(data.typeData)
        data.leftAmount = sum(Object.values(data.typeData).map(el => el.leftAmount || 0))
        return data
      })
      if (result.length > 1) {
        const typeData = PayOutTypeEnum.getOptions().reduce((r, a) => {
          r[a.value] = {
            payOutAmount: sum(result.map(el => el.typeData[a.value].payOutAmount || 0)),
            originPayOutAmount: sum(result.map(el => el.typeData[a.value].originPayOutAmount || 0)),
            payOutCount: sum(result.map(el => el.typeData[a.value].payOutCount || 0)),
            lastPayOutCount: sum(result.map(el => el.typeData[a.value].lastPayOutCount || 0))
          }
          if (a.value === PayOutTypeEnum.AUTO.id || a.value === PayOutTypeEnum.TS.id) {
            r[a.value].leftAmount = 0
          } else {
            r[a.value].leftAmount = Math.round((r[a.value].originPayOutAmount - r[a.value].payOutAmount) * 100) / 100
          }
          r[a.value].payOutCountIncRate = r[a.value].lastPayOutCount > 0 ?
            ((r[a.value].payOutCount - r[a.value].lastPayOutCount) / r[a.value].lastPayOutCount).toFixed(2)
            : (r[a.value].payOutCount > 0 ? 100 : 0)
          return r
        }, {})
        const payOutCount = sum(Object.values(typeData).map(el => el.payOutCount))
        const lastPayOutCount = sum(Object.values(typeData).map(el => el.lastPayOutCount))
        const payOutAmount = sum(Object.values(typeData).map(el => el.payOutAmount))
        const originPayOutAmount = sum(Object.values(typeData).map(el => el.originPayOutAmount))
        const leftAmount = sum(Object.values(typeData).map(el => el.leftAmount))
        // console.log(typeData)
        result.push({
          storeName: '总计',
          typeData,
          originPayOutAmount,
          leftAmount: leftAmount.toFixed(2),
          payOutAmount,
          payOutCountIncRate: lastPayOutCount > 0 ? ((payOutCount - lastPayOutCount) / lastPayOutCount).toFixed(2) : (
            payOutCount > 0 ? 100 : 0
          )
        })
        Object.values(typeData).forEach(t => {
          t.payOutAmountRate = payOutAmount > 0 ? (t.payOutAmount / payOutAmount * 100).toFixed(2) : 0
        })
      }
      return result
    })
  }

  round(v) {
    return Math.round(v * 100) / 100
  }

  queryUserDeliveryComplainStaticList({
    dateRange
  }) {
    return this.get('user-delivery-complain-static', {
      startDate: dateRange[0],
      endDate: dateRange[1]
    }).then(dataList => {
      if (dataList && dataList.length > 1) {
        const item = {
          userName: '合计',
          backCount: dataList.reduce((r, a) => r + a.backCount, 0),
          otherBackCount: dataList.reduce((r, a) => r + a.otherBackCount, 0),
          backCountRate: 100,
          otherBackCountRate: 100,
          payOutAmountSum: this.round(dataList.reduce((r, a) => r + a.payOutAmountSum, 0)),
          backOutAmountSum: this.round(dataList.reduce((r, a) => r + a.backOutAmountSum, 0)),
          otherBackOutAmountSum: this.round(dataList.reduce((r, a) => r + a.otherBackOutAmountSum, 0)),
          otherPayOutAmountSum: this.round(dataList.reduce((r, a) => r + a.otherPayOutAmountSum, 0)),
          backOutAmountRate: 100,
          otherBackOutAmountRate: 100,
          lastBackCount: dataList.reduce((r, a) => r + a.lastBackCount, 0),
          lastOtherBackCount: dataList.reduce((r, a) => r + a.lastOtherBackCount, 0),
          ranking: ''
        }
        item.avgBackOutAmount = item.backCount > 0 ? this.round(item.payOutAmountSum / item.backCount) : 0
        dataList.push(item)
        dataList.forEach((item, i) => {
          item.ranking = i + 1
          item.lastTotalBackCount = item.lastBackCount + item.lastOtherBackCount
          item.totalBackCount = item.backCount + item.otherBackCount
          item.leftAmount = this.round(item.payOutAmountSum - item.backOutAmountSum)
          item.otherLeftAmount = this.round(item.otherPayOutAmountSum - item.otherBackOutAmountSum)
          item.totalLeftAmount = this.round(item.leftAmount + item.otherLeftAmount)
          item.totalPayOutAmountSum = this.round(item.payOutAmountSum + item.otherPayOutAmountSum)
          item.avgBackOutAmount = item.backCount > 0 ? this.round(item.backOutAmountSum / item.backCount) : 0
          if (item.lastTotalBackCount > 0) {
            item.backCountIncRate = ((item.totalBackCount - item.lastTotalBackCount) / (item.lastTotalBackCount) * 100).toFixed(2)
          } else if (item.backCount > 0) {
            item.backCountIncRate = 100
          } else {
            item.backCountIncRate = 0
          }
        })
        item.ranking = ''
      }
      return dataList
    })
  }

  queryDailyReport({
    dateRange
  }) {
    return this.get('daily-report', {
      startDate: dateRange[0],
      endDate: dateRange[1]
    }).then(dataList => {
      const storeDateToPayoutAmountMap = {}
      const storeDateToBackoutAmountMap = {}
      for (const item of dataList) {
        const key = `${item.storeTitle}-${item.date}`
        storeDateToPayoutAmountMap[key] = item.payOutAmountSum
        storeDateToBackoutAmountMap[key] = item.backOutAmountSum
      }
      // console.log(storeDateToPayoutAmountMap)
      // console.log(storeDateToBackoutAmountMap)
      // dateRange[0] 到 dateRange[1] 之间的所有日期, dataRange[0] 格式为 yyyy-MM-dd 字符串
      const dateList = []
      const date = moment(dateRange[0])
      const endDate = moment(dateRange[1])
      while (date.isSameOrBefore(endDate)) {
        dateList.push(date.format('YYYY-MM-DD'))
        date.add(1, 'days')
      }
      // console.log(dateList)

      const storeTitleList = Array.from(new Set(dataList.map(item => item.storeTitle)))
      const rows = []
      const colSum = []
      const colSumForPayout = []

      for (let i = 0; i < storeTitleList.length; i++) {
        const row = []
        row.push(storeTitleList[i])
        // for row
        let payOutAmountSum = 0
        // 列
        for (let j = 0; j < dateList.length; j++) {
          const title = dateList[j]
          // if (j === dateList.length - 1) {
          //   row.push(payOutAmountSum)
          //   colSum[j + 1] = round((colSum[j] || 0) + payOutAmountSum)
          //   continue
          // }
          const key = `${storeTitleList[i]}-${title}`
          row.push(storeDateToBackoutAmountMap[key] || 0)
          payOutAmountSum += storeDateToBackoutAmountMap[key] || 0
          colSum[j] = round((colSum[j] || 0) + (storeDateToBackoutAmountMap[key] || 0))
          colSumForPayout[j] = 0 // round((storeDateToPayoutAmountMap[j] || 0) + (storeDateToPayoutAmountMap[key] || 0))
        }
        row.push(round(payOutAmountSum))
        rows.push(row)
      }
      const totalRow = ['汇总', ...colSum, sum(colSum)]
      rows.push(totalRow)
      // 申诉金额
      const backCountRow = ['申诉金额', ...colSumForPayout, sum(colSumForPayout)]
      rows.push(backCountRow)
      // 实际赔付汇总, 实际赔付汇总 = 汇总 - 申诉金额
      const finalColumns = colSum.map((item, i) => round(item - colSumForPayout[i]))
      const actualPayOutRow = ['实际赔付汇总', ...finalColumns, sum(finalColumns)]
      rows.push(actualPayOutRow)
      const titleList = [
        '店铺',
        ...dateList,
        '发货投诉本月汇总'
      ]
      return {
        titleList,
        titleLength: titleList.length,
        rows
      }
    })
  }

  removeByCondition(condition) {
    return this.post('remove-by-cond', condition)
  }
}

function round(num) {
  return Math.round(num * 100) / 100
}

function sum(arr) {
  return Math.round(arr.reduce((r, a) => a + r, 0) * 100) / 100
}

export const deliveryComplainApi = new DeliveryComplainApi()
